package com.ayf.payment.game.api.controller.player;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.cache.redis.RedisCacheUtil;
import com.ayf.payment.game.api.dto.ParAndTemInfoDTO;
import com.ayf.payment.game.api.dto.player.PlayerInfoApiDTO;
import com.ayf.payment.game.api.dto.player.PlayerKeyUtil;
import com.ayf.payment.game.api.dto.player.PlayerPhoneDTO;
import com.ayf.payment.game.api.entity.MerchantConfig;
import com.ayf.payment.game.api.entity.platform.WxConfig;
import com.ayf.payment.game.api.httpclient.HttpUtils;
import com.ayf.payment.game.api.service.MerchantConfigService;
import com.ayf.payment.game.api.service.TemplateService;
import com.ayf.payment.game.api.service.platform.WxConfigService;
import com.ayf.payment.game.api.utils.RandomStrUtils;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.ayf.payment.integral.dto.IntegralDTO;
import com.ayf.payment.integral.exception.IntegralInfoException;
import com.ayf.payment.integral.service.remote.IntegralRemoteService;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author: zh-liang
 * @Date : 2020-08-20 14:10
 */
@Component
public class PlayerApi {
    //        private static final String HOST = "http://127.0.0.1:9000";
    private static final String PLATFORM_CODE = System.getenv("GAME_AYFPAY_PLATFORM_CODE");
    private static final String HOST = System.getenv("GAME_AYFPAY_INTEGRAL_HOST");

    private static final String PLAYER_SEND_SMS_URL = "/p2/sms";
    private static final String PLAYER_GET_PLAYER_INFO_URL = "/p2/getPlayerInfo";
    private static final String PLAYER_REGISTER_URL = "/p2/register";
    private static final String PLAYER_GET_PHONE_BY_IDS_URL = "/p2/getPlayerInfo";
    private static final String CODE = "code";
    private static final String DATA = "data";

    @Resource
    private RedisCacheUtil redisCacheUtil;
    @Autowired
    private WxConfigService wxConfigService;
    @Reference(version = "1.0.0",check = false)
    private IntegralRemoteService integralRemoteService;
    @Resource
    private MerchantConfigService merchantConfigService;
    @Resource
    private TemplateService templateService;

    public boolean sendSms(String phone, String type) {
        String traceId = SnowFlakeUtils.getTraceId();
        try {
            String code = RandomStrUtils.createRandom(true, 6);
            String url = HOST + PLAYER_SEND_SMS_URL + "?phone=" + phone + "&type=" + type + "&code=" + code;
            Map<String, String> map = HttpUtils.doGet(traceId, url);
            if ("200".equals(map.get(CODE))) {
                redisCacheUtil.setObjectToCache(PlayerKeyUtil.getSmsKey(type, phone), code, 30L, TimeUnit.MINUTES);
                return true;
            } else {
                LogPortal.error("[{}]手机号[{}]发送短信失败，返回信息为[{}]", traceId, phone, JSON.toJSONString(map));
            }
        } catch (Exception e) {
            LogPortal.error("[{}]手机号[{}]发送短信失败，发生[{}]异常，异常信息为[{}]", traceId, phone, e.getClass().getSimpleName(), e.getMessage());
        }
        return false;
    }

    public PlayerInfoApiDTO getPlayerInfo(String phone) {
        String traceId = SnowFlakeUtils.getTraceId();
        try {
            String url = HOST + PLAYER_GET_PLAYER_INFO_URL + "?phone=" + phone;
            Map<String, String> map = HttpUtils.doGet(traceId, url);
            if ("200".equals(map.get(CODE))) {
                JSONObject jsonObject = JSON.parseObject(map.get(DATA));
                Integer code = jsonObject.getInteger("code");
                if (code == 200) {
                    JSONObject data = jsonObject.getJSONObject("data");
                    return JSON.toJavaObject(data, PlayerInfoApiDTO.class);
                } else {
                    throw new IntegralInfoException(code, jsonObject.getString("msg"));
                }
            } else {
                LogPortal.error("[{}]手机号[{}]发送短信失败，返回信息为[{}]", traceId, phone, map);
            }
        } catch (IntegralInfoException e) {
            throw e;
        } catch (Exception e) {
            LogPortal.error("[{}]获取玩家信息失败，发生[{}]异常，异常信息为[{}]",e,traceId, e.getClass().getSimpleName(), e.getMessage());
        }
        return null;
    }

    public List<PlayerPhoneDTO> getPhoneByIds(List<Long> ids) {
        String traceId = SnowFlakeUtils.getTraceId();
        try {
            Map<String, Object> mapPar = new HashMap<>();
            mapPar.put("ids", ids);
            String jsonReqData = JSONObject.toJSONString(mapPar);
            Map<String, String> map = HttpUtils.noSignPost(traceId, HOST + PLAYER_GET_PHONE_BY_IDS_URL, jsonReqData);
            if ("200".equals(map.get(CODE))) {
                JSONObject jsonObject = JSON.parseObject(map.get(DATA));
                Integer code = jsonObject.getInteger("code");
                if (code == 200) {
                    String data = jsonObject.getString("data");
                    return JSONArray.parseArray(data, PlayerPhoneDTO.class);
                } else {
                    throw new IntegralInfoException(code, jsonObject.getString("msg"));
                }
            } else {
                LogPortal.error("[{}]获取手机信息失败，参数[{}]返回信息为[{}]", traceId, JSON.toJSONString(ids), map);
            }
        } catch (IntegralInfoException e) {
            throw e;
        } catch (Exception e) {
            LogPortal.error("[{}]获取手机信息失败，发生[{}]异常，异常信息为[{}]", traceId, e.getClass().getSimpleName(), e.getMessage());
        }
        return null;
    }

    public boolean isExist(String phone) {
        String traceId = SnowFlakeUtils.getTraceId();
        try {
            String url = HOST + PLAYER_GET_PLAYER_INFO_URL + "?phone=" + phone;
            Map<String, String> map = HttpUtils.doGet(traceId, url);
            if ("200".equals(map.get(CODE))) {
                JSONObject jsonObject = JSON.parseObject(map.get(DATA));
                Integer code = jsonObject.getInteger("code");
                if (code == 200) {
                    return true;
                }
                if (code == 201) {
                    return false;
                }
            } else {
                LogPortal.error("[{}]手机号[{}]获取玩家信息失败，返回信息为[{}]", traceId, phone, map);
            }
        } catch (IntegralInfoException e) {
            throw e;
        } catch (Exception e) {
            LogPortal.error("[{}]获取玩家信息失败，发生[{}]异常，异常信息为[{}]", traceId, e.getClass().getSimpleName(), e.getMessage());
        }
        return true;
    }

    public PlayerInfoApiDTO apiRegister(String phone, String weChatName) {
        if (StringUtils.isEmpty(phone)){
            LogPortal.error("手机号[{}]开户失败，手机号不能为空",phone);
            return null;
        }
        String traceId = SnowFlakeUtils.getTraceId();
        if (!Validator.isMobile(phone)) {
            LogPortal.error("[{}]手机号[{}]开户失败，手机号格式错误", traceId, phone);
            return null;
        }
        try {
            Map<String, String> mapPar = new HashMap<>();
            mapPar.put("phone", phone);
            mapPar.put("weChatName", weChatName);
            String jsonReqData = JSONObject.toJSONString(mapPar);
            Map<String, String> map2 = HttpUtils.noSignPost(traceId, HOST + PLAYER_REGISTER_URL, jsonReqData);
            if ("200".equals(map2.get(CODE))) {
                JSONObject jsonObject2 = JSON.parseObject(map2.get(DATA));
                Integer code2 = jsonObject2.getInteger("code");
                if (code2 == 200) {
                    LogPortal.error("[{}]手机号[{}]开户成功", traceId, phone);
                    JSONObject data = jsonObject2.getJSONObject("data");
                    return JSON.toJavaObject(data, PlayerInfoApiDTO.class);
                } else {
                    LogPortal.error("[{}]手机号[{}]开户失败,原因[{}]", traceId, phone, jsonObject2.getString("msg"));
                }
            } else {
                LogPortal.error("[{}]手机号[{}]开户失败，返回信息为[{}]", traceId, phone, map2);
            }
        } catch (Exception e) {
            LogPortal.error("[{}]玩家开户失败，发生[{}]异常，异常信息为[{}]",e,traceId, e.getClass().getSimpleName(), e.getMessage());
        }
        return null;
    }

    public PlayerInfoApiDTO loginRegister(String phone, Integer merchantId) {
        WxConfig wxConfig = wxConfigService.getGameConfigByMerchantRelationId(merchantId);
        if (wxConfig != null && StrUtil.isNotBlank(wxConfig.getName()) && wxConfig.getStatus() == 1) {
            return apiRegister(phone, wxConfig.getName());
        } else {
            LogPortal.error("公众号端注册 手机号[{}]开户失败，商户[{}]微信配置错误", phone, wxConfig, JSON.toJSONString(wxConfig));
            return null;
        }
    }

    public void register(String phone, Integer merchantId,String partitionId) {
        try {
            if (StringUtils.isEmpty(phone)){
                return;
            }
            ParAndTemInfoDTO temInfoDTO = templateService.selectTemInfo(partitionId);
            if (temInfoDTO.getIsGiveIntegral() == 0) {
                LogPortal.info("充值界面 手机号[{}]开户失败，当前模板是否增加积分设置为否，模板id[{}-{}]", phone, temInfoDTO.getTemplateId(), temInfoDTO.getTemplateName());
                return;
            }
            MerchantConfig merchantConfig = merchantConfigService.selectOne(merchantId);
            if (merchantConfig.getPlayerIntegralExStatus() == 0) {
                LogPortal.info("充值界面 手机号[{}]开户失败[充值赠送积分状态为关闭]", phone);
                return;
            }
            WxConfig wxConfig = wxConfigService.getGameConfigByMerchantRelationId(merchantId);
            if (wxConfig != null && StrUtil.isNotBlank(wxConfig.getName()) && wxConfig.getStatus() == 1) {
                if (isExist(phone)) {
                    LogPortal.info("充值界面 手机号[{}]已注册", phone);
                    return;
                }
                apiRegister(phone, wxConfig.getName());
            } else {
                LogPortal.error("充值界面 手机号[{}]开户失败，商户[{}]微信配置错误", phone, merchantId, JSON.toJSONString(wxConfig));
            }
        } catch (Exception e) {
            LogPortal.error("register 充值界面 商户ID:{} 手机号[{}]开户失败 ",merchantId,phone);
        }
    }

    public void rechargeAdd(String phone, Integer merchantId, String orderNo, BigDecimal amount, String partitionId) {
        try {
            if (StringUtils.isEmpty(phone)){
                return;
            }
            if (!Validator.isMobile(phone)) {
                LogPortal.error("充值成功 手机号[{}]增加积分失败，手机号格式错误", phone);
                return;
            }
            ParAndTemInfoDTO temInfoDTO = templateService.selectTemInfo(partitionId);
            if (temInfoDTO.getIsGiveIntegral()==0) {
                LogPortal.info("充值成功 手机号[{}]增加积分失败，当前模板是否增加积分设置为否，模板id[{}-{}]", phone, temInfoDTO.getTemplateId(),temInfoDTO.getTemplateName());
                return;
            }
            MerchantConfig merchantConfig = merchantConfigService.selectOne(merchantId);
            if (merchantConfig.getPlayerIntegralExStatus() == 0) {
                LogPortal.info("充值成功 手机号[{}]增加积分失败[充值赠送积分状态为关闭]", phone);
                return;
            }
            PlayerInfoApiDTO playerInfo = null;
            try {
                playerInfo = getPlayerInfo(phone);
            } catch (IntegralInfoException e) {
                LogPortal.info("充值成功 手机号[{}]增加积分失败[账户不存在]", phone);
                return;
            }
            if (playerInfo == null) {
                LogPortal.info("充值成功 手机号[{}]增加积分失败[查询账号信息为空]", phone);
                return;
            }
            WxConfig wxConfig = wxConfigService.getGameConfigByMerchantRelationId(merchantId);
            if (wxConfig == null || wxConfig.getStatus() == 0 || wxConfig.getMerchantId() == null) {
                LogPortal.info("充值成功 手机号[{}]增加积分失败[微信配置不正确：{}]", phone, JSON.toJSONString(wxConfig));
                return;
            }
            long val = amount.setScale(0, BigDecimal.ROUND_DOWN).longValue();
            IntegralDTO dto = new IntegralDTO();
            dto.setVal(val);
            dto.setRemark("充值");
            dto.setType(1);
            dto.setPlatformCode(PLATFORM_CODE);
            dto.setGmId(wxConfig.getMerchantId());
            dto.setExOrderSerialNo(orderNo);
            dto.setPlayerId(playerInfo.getId());
            if(integralRemoteService != null){
                integralRemoteService.changeIntegral(dto);
                LogPortal.info("充值成功 手机号[{}]增加积分[{}]成功", phone, val);
            }
        } catch (Exception e) {
            LogPortal.info("充值成功 手机号[{}]增加积分[{}]失败",e,phone);
        }
    }

}
